<?php
require_once(dirname(__FILE__) . '/../../includes/spip_launcher.php');
include_spip('functions/pdk_common');
require_once(_DIR_PLUGIN_PDK.'classes/simpletest/class.PdkModelTest.php');

class TestClassProductModel extends PdkModelTest {
    /**
     *  CurrencyModel
     */
    protected $currency_mdl;
    /**
     *  RubriqueCurrencyModel
     */
    private $rub_cur_mdl;
    
    /**
     *  PdkRubriqueModel
     */
    private $rub_mdl;
    
    /**
     *  PdkArticleModel
     */
    private $art_mdl;
    
    /**
     *  CompositeArticleModel
     */
    private $composite_art_mdl;
    
    public function __construct(){
        parent::__construct();
        
        // Define all additional models:
        $pdk_models = array();
        $this->rub_cur_mdl = pdk_load_class('RubriqueCurrencyModel','classes');
        $pdk_models['RubriqueCurrencyModel'] = $this->rub_cur_mdl;
        $this->rub_mdl = pdk_load_class('PdkRubriqueModel','classes/models');
        $pdk_models['PdkRubriqueModel'] = $this->rub_mdl;        
        $this->art_mdl = pdk_load_class('PdkArticleModel','classes/models');
        $pdk_models['PdkArticleModel'] = $this->art_mdl;
        $this->currency_mdl = pdk_load_class('CurrencyModel','classes');
        $pdk_models['CurrencyModel'] = $this->currency_mdl;
        $this->composite_art_mdl = pdk_load_class('CompositeArticleModel','classes');
        $pdk_models['CompositeArticleModel'] = $this->composite_art_mdl;
        
        $this->AddPdkModels($pdk_models);
        
        // Set main (tested) model:
        $this->SetPdkModel('ProductModel', pdk_load_class('ProductModel', 'classes'));
        $this->dropTestTables = ECATALOGUE_TESTS_DROP_TEST_TABLES;
        
        // Remember current currency ID
        $this->current_currency_id = $this->currency_mdl->GetCurrentCurrencyId();
    }
    
    /**
     *  Run before each test
     */
    function setUp() {
        parent::setUp();            
    }
    
    /**
     *  Run after each test
     */
    function tearDown() {
        parent::tearDown();
    }
    
    function __destruct() {
        // Call parent destructor to delete created tables
        parent::__destruct();
        // Restore initial current currency ID
        $this->currency_mdl->SetCurrentCurrencyId($this->current_currency_id);
    }
    
    function testGetProductPrice() {        
        // Price, converted to currency wich is attached to article 1
        $price = $this->model->GetProductPrice(1);        
        $price_check = $this->model->test_data[0]['price']*$this->currency_mdl->test_data[0]['rate'];        
        $this->assertEqual($price_check, $price);
        
        // Price, directly converted to some currency
        $price = $this->model->GetProductPrice(1, $this->currency_mdl->test_data[1]['code']);
        $price_check = $this->model->test_data[0]['price']*$this->currency_mdl->test_data[1]['rate'];
        $this->assertEqual($price_check, $price);
        
        // old Price, converted to currency wich is attached to article 1
        $price = $this->model->GetProductPrice(1, false, 'priceold');        
        $price_check = $this->model->test_data[0]['priceold']*$this->currency_mdl->test_data[0]['rate'];        
        $this->assertEqual($price_check, $price);
        
        // Old Price, directly converted to some currency
        $price = $this->model->GetProductPrice(1, $this->currency_mdl->test_data[1]['code'], 'priceold');
        $price_check = $this->model->test_data[0]['priceold']*$this->currency_mdl->test_data[1]['rate'];
        $this->assertEqual($price_check, $price);
    }
    
    function testGetProductPriceCompositeProducts() {        
        // Make product composite
        $this->model->update_by_id(1, array('is_composite'=>1));
        // Get price of first product in UAH
        $price = $this->model->GetProductPrice(1, $this->currency_mdl->test_data[1]['code']);
        // Although Product #1 is composite, it's own price must be returned because it isn't 0        
        $price_check = $this->model->test_data[0]['price']*$this->currency_mdl->test_data[1]['rate'];
        $this->assertEqual($price_check, $price);
        
        // Set price to 0 and make product composite
        $this->model->update_by_id(1, array('price'=>0, 'is_composite'=>1));
        // Get price of first product in USD
        $price = $this->model->GetProductPrice(1, $this->currency_mdl->test_data[0]['code']);
        // Product #1 is composite and consist of products #2 and #3, so it's price must be their sum
        $price_check = $this->model->test_data[1]['price']*$this->currency_mdl->test_data[0]['rate']*$this->composite_art_mdl->test_data[0]['quantity'] + 
                       $this->model->test_data[2]['price']*$this->currency_mdl->test_data[0]['rate']*$this->composite_art_mdl->test_data[1]['quantity'];        
        $this->assertEqual($price_check, $price);
    }
	
	function testGetPriceCompositeProducts_OldPrice() {
		// Set price to 100 and make product composite
        $this->model->update_by_id(1, array('priceold'=>100, 'is_composite'=>1));
		// Get priceold of first product in UAH
        $priceold = $this->model->GetProductPrice(1, $this->currency_mdl->test_data[1]['code'], 'priceold');
		// Priceold of product #1 must be 100
		$this->assertEqual(100, $priceold);
	
		// Set priceold to 0 and make product composite
        $this->model->update_by_id(1, array('priceold'=>0, 'is_composite'=>1));
		// Get priceold of first product in USD
        $priceold = $this->model->GetProductPrice(1, $this->currency_mdl->test_data[0]['code'], 'priceold');
		// Product #1 is composite and consist of products #2 and #3, but its priceold must be 0, because priceold is taken only from product itself
		$this->assertEqual(0, $priceold);
	}
    
    function TestGetProductPriceNoCurrency() {
        // Delete all rubrique-currency links
        $this->rub_cur_mdl->delete();
        
        // Set UAH as current currency
        $this->currency_mdl->SetCurrentCurrencyId(2);       
        $price = $this->model->GetProductPrice(1);
        $price_check = $this->model->test_data[0]['price'];
        $this->assertEqual($price_check, $price);
        
        // Set USD as current currency
        $this->currency_mdl->SetCurrentCurrencyId(1);
        $price = $this->model->GetProductPrice(1);
        $price_check = $this->model->test_data[0]['price']*$this->currency_mdl->test_data[0]['rate'];
        $this->assertEqual($price_check, $price);
    }
    
    function testGetMaxIdEquipment() {        
        $this->assertEqual(2, $this->model->GetMaxIdEquipment());
        $this->model->insert(array('id_equipment'=>4));
        $this->assertEqual(4, $this->model->GetMaxIdEquipment());
    }
    
    function testInsertOneRow_DataWithoutIdEquipment() {
        $data = $this->model->test_data[0];
        $data[$this->model->primary_key] = 999;
        unset($data['id_equipment']);
        
        $data_check = $data;        
        $data_check['id_equipment'] = $this->model->GetMaxIdEquipment()+1;
        
        $this->model->insert($data);
        
        $data_article = $this->art_mdl->form_data_from_array($data);
        $this->art_mdl->insert($data_article);
        
        $data_sel = $this->model->select_by_id($data[$this->model->primary_key]);
        
        $this->assertEqual($data_check, $data_sel);
    }
}
